@page "/viewcode/{Guid}"
@using Microsoft.CodeAnalysis.Sarif;
@using System.Text;
@inject Blazored.LocalStorage.ILocalStorageService localStorage;
@inject IJSRuntime JSRuntime;

    <div>
        @if (FileName != null)
        {
            <h1>@FileName</h1>
            <p>Run: <a href="Reports/@Results.RunIdMap.Where(x => x.Value == RunId).FirstOrDefault().Key">@RunId</a></p>
            @foreach (var result in filteredResults)
            {
    <div style="border-radius: 25px; border: 2px solid #808080; padding: 20px;">
        <p><i>@result.RuleId: @result.Message.Text - @GetSeverityForRule(result.RuleId)</i></p>
        <h3>Description</h3>
        <p>@loadedSarif?.Runs[0].Tool.Driver.Rules.Where(x => x.Id == result.RuleId).FirstOrDefault()?.FullDescription.Text</p>
        <pre class="match-braces rainbow-braces line-numbers lang-@Language" data-line="@result.Locations[0].PhysicalLocation.Region.StartLine-@result.Locations[0].PhysicalLocation.Region.EndLine" data-start="@Math.Max(0,result.Locations[0].PhysicalLocation.Region.StartLine-5)"><code style="display:block; white-space:pre-wrap">
@GetContextFromLine(result.Locations[0].PhysicalLocation.Region.StartLine, result.Locations[0].PhysicalLocation.Region.EndLine, 5)
            </code></pre>
    </div>

            }
        }
        else
        {
            <p>Could not fetch file information given @Guid</p>
        }
    </div>


@code {
    private FailureLevel GetSeverityForRule(string ruleId)
    {
        var severities = loadedSarif.Runs[0].Tool.Driver.Rules.Where(y => y.Id == ruleId);
        var severity = FailureLevel.Note;
        if (severities.Any())
            severity = severities.Max(x => x.DefaultConfiguration.Level);
        return severity;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await JSRuntime.InvokeVoidAsync("highlightCode");
    }

    public string GetContextFromLine(int startLine, int endLine, int numLinesContext)
    {
        var start = Math.Max(0, startLine - numLinesContext);
        var end = Math.Min(CodeLines.Length, endLine + numLinesContext - 1);
        return string.Join(Environment.NewLine, CodeLines[start..end]);
    }

    [Parameter]
    public string Guid { get; set; } = "Not Provided";

    public string? FileName { get; set; }

    public string? Code { get; set; }

    public string[] CodeLines { get; set; } = Array.Empty<string>();

    public string? Language { get; set; }

    public string? RunId { get; set; }

    private List<Result> filteredResults = new List<Result>();

    private Results Results;

    private SarifLog loadedSarif;

    protected override async Task OnInitializedAsync()
    {
        Results = await localStorage.GetItemAsync<Results>("DevSkimResults");
        var theGuid = Guid;
        var codeFile = await localStorage.GetItemAsync<CodeFile>(Guid);

        Code = codeFile.Content;
        CodeLines = Code?.Split(Environment.NewLine) ?? Array.Empty<string>();
        FileName = codeFile.FileName;
        Language = Microsoft.DevSkim.Language.FromFileName(FileName ?? string.Empty);
        RunId = codeFile.RunId;

        if (RunId != null)
        {
            var sarif = await localStorage.GetItemAsStringAsync(Results.ResultLocations[RunId]);
            using var stream = new System.IO.MemoryStream(Encoding.UTF8.GetBytes(sarif));
            loadedSarif = SarifLog.Load(stream);
            var results = loadedSarif.Runs[0].Results;
            var preparedFileName = System.IO.Path.GetFullPath(FileName ?? string.Empty);

            if (results != null)
            {
                foreach (var result in results)
                {
                    foreach (var location in result.Locations)
                    {
                        if (preparedFileName.Equals(location.PhysicalLocation.Address.FullyQualifiedName))
                        {
                            filteredResults.Add(result);
                            break;
                        }
                    }
                }
            }
        }
        this.StateHasChanged();
    }
}
